package work.huangxin.share.controller.classSchedule;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import work.huangxin.share.domain.other.UserMessage;
import work.huangxin.share.domain.other.WXSessionModel;
import work.huangxin.share.domain.schedule.ClassSchedule;
import work.huangxin.share.domain.schedule.ClassScheduleNote;
import work.huangxin.share.domain.schedule.ClassSecheduleVO;
import work.huangxin.share.domain.schedule.Weather;
import work.huangxin.share.domain.weather.Casts;
import work.huangxin.share.domain.weather.Forecast;
import work.huangxin.share.domain.weather.WeatherResponse;
import work.huangxin.share.service.CityAdcodeService;
import work.huangxin.share.service.ClassScheduleService;
import work.huangxin.share.service.impl.UserMessageOperationService;
import work.huangxin.share.util.ParseWeekDay;
import work.huangxin.share.util.common.HttpClientUtil;
import work.huangxin.share.util.status.BaseResponse;
import work.huangxin.share.util.status.CodeEnum;
import work.huangxin.share.util.status.ResponseData;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author: 张锦标
 * @date: 2023/4/17 19:07
 * ClassScheduleController类
 * 课表控制类
 */
@RequestMapping("/wx/class/schedule")
@RestController
public class ClassScheduleController {
    @Autowired
    private ClassScheduleService classScheduleService;

    /**
     * 保存天气信息
     */
    private HashMap<String,Forecast[]> weatherHashMap = new HashMap<>();

    @Autowired
    private UserMessageOperationService userMessageOperationService;

    @Autowired
    @Qualifier("logThreadPool")
    private  ThreadPoolExecutor threadPoolExecutor;

    /**
     * 获取当前用户的所有课表 一整个学期的
     *
     * @param userId
     * @return
     */
    @GetMapping("/all/{userId}")
    public BaseResponse getAllClassSchedulesWithNotes(@PathVariable("userId") Long userId) {
        //TODO 当前方法用于返回当前用户一整个学期的所有课表
        //TODO 同时需要把课表对应的笔记也一并返回回去
        return ResponseData.success();
    }

    /**
     * 这个是获取某一周的课表信息
     * 当然 也可以直接一次性返回一整个学期的 那么就不需要这个接口了
     * 看自己想如何实现 使用这个的话 好处在于 传递的数据量少 速度快
     * 上面那个接口的好处在于省事
     *
     * @param userId
     * @return
     */
    @GetMapping("/week/{userId}")
    public BaseResponse getThisWeekClassSchedules(@PathVariable("userId") Long userId) {
        //TODO 根据当前周 获取这一整周的课表
        return ResponseData.success();
    }

    /**
     * 返回当前一整周的天气 可以选定城市 或者直接写固定值 某个地区
     * 如果当前的日期已经不是周一 那么之前几天的天气
     * 返回一个默认值 比如 当天已过 希望你那天开心 类型这样子
     *
     * @param city
     * @return
     */
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private  RestTemplate restTemplate;

    @Autowired
    private CityAdcodeService cityAdcodeService;



    @GetMapping("/getClassSchedule")
    public BaseResponse getClassSchedule(HttpServletRequest request) {
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        //用于用户首次登入教务系统，判断用户是否已经在教务系统中注册教务系统信息
        UserMessage userMessage = userMessageOperationService.getUserMessage(user.getUserId());
        if (null == userMessage.getCampusId()){
            //用户未绑定教务系统信息
            return ResponseData.success();
        }
        //判断数据库中是否有该班级课表
        List<ClassSecheduleVO> classSecheduleVOS = classScheduleService
                .getClassScheduleWithNoteByClazzName(user.getUserId(),userMessage.getClazzName());
        if (Objects.isNull(classSecheduleVOS)){
            return ResponseData.error(CodeEnum.NOT_FOUND);
        }
        return ResponseData.success(classSecheduleVOS);
        //List<ClassSecheduleVO> list = classScheduleService.
        //        getClassScheduleWithNoteByClazzName(28, "电子信息2004");
        //return ResponseData.success(list);
    }

    private static Casts[] casts = new Casts[3];

    /**
     * 每天12：00运行一次,项目启动自动加载数据
     */
    @Scheduled(cron = "0 0 0 1 * ? ")
    @PostConstruct
    public void initBlackList()
     {
        //清空天气表中的数据
         weatherHashMap.clear();
     }

    /**
     * 获得本周天气，本天前的天气返回鸡汤
     * @param city
     * @return
     */
    @GetMapping("/getWeather")
    public BaseResponse getWeather(@RequestParam String city) {
        int days = ParseWeekDay.getDays();
        Weather[] weathers = new Weather[7];
        //首先判断当前离本周一的时间
        for (int i = 0; i < days; i++) {
            HashMap blessing = classScheduleService.getBlessing();
            Weather weather = new Weather();
            weather.setType("message");
            weather.setNotice((String)blessing.get("hitokoto"));
            weathers[i] = weather;
        }
        Forecast[] casts1 = weatherHashMap.get(city);

        if (null == casts1 || casts1.length == 0){
            //根据城市名到数据库中查询id
            //自己发送request请求
            casts1 = getWeatherByCityId(city);
            if (null == casts1 || casts1.length == 0){
                return ResponseData.error(404,"暂不支持该城市");
            }
        }
        for (int i = 0; i < weathers.length - days; i++) {
            //剩下几天从天气接口中得到
            Weather weather = new Weather();
            weather.setType("weather");
            weather.setForecast(casts1[i]);
            weathers[days + i] = weather;
        }
        return ResponseData.success(weathers);
    }

    public Forecast[] getWeatherByCityId(String cityName){
        Integer cityId = cityAdcodeService.getAdcodeByCityName(cityName);
        if (null == cityId){
            return null;
        }
        OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .connectTimeout(180, TimeUnit.SECONDS)
                .readTimeout(180, TimeUnit.SECONDS)
                .writeTimeout(180, TimeUnit.SECONDS)
                .build();
        //高德地图api
//         HttpUrl.Builder urlbuilder = HttpUrl.parse("https://restapi.amap.com/v3/weather/weatherInfo").newBuilder();
//         urlbuilder.addQueryParameter("key","d100ba7ba2544f288f21c295f15c5db7");
//         urlbuilder.addQueryParameter("city","430211");
//         urlbuilder.addQueryParameter("extensions","all");
        HttpUrl.Builder urlbuilder = HttpUrl.parse("http://t.weather.sojson.com/api/weather/city/" + cityId)
                .newBuilder();

        Request request = new Request.Builder().url(urlbuilder.build()).build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            String result = response.body().string();
            WeatherResponse weatherResponse = JSONObject.parseObject(result, WeatherResponse.class);
            Forecast[] forecasts = weatherResponse.getData().getForecast();
            weatherHashMap.put(cityName, forecasts);
            return forecasts;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
